package com.winit.openapi.oauth.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiBizException;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.oauth.entity.APISystemConfigEntity;
import com.winit.openapi.oauth.manager.APISystemConfigManager;
import com.winit.openapi.util.ValidateUtil;

@Controller
@RequestMapping(value = "winit/api/config")
public class APIConfigController extends BaseController {

    private Logger                 logger = LoggerFactory.getLogger(APIConfigController.class);

    @Resource
    private APISystemConfigManager apiSystemConfigManager;

    @RequestMapping(value = "/create")
    public String create(@ModelAttribute RequestMsg requestMsg) {

        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "configKey");
            ValidateUtil.validNotNull(json, "configValue");
            ValidateUtil.validMaxLength(json, "configKey", 60, true);
            ValidateUtil.validMaxLength(json, "configValue", 60, true);
            if (json.containsKey("description")) {
                ValidateUtil.validMaxLength(json, "description", 100, false);
            }
            String configKey = json.getString("configKey");

            try {
                if (apiSystemConfigManager.checkExists(configKey)) {
                    throw new ApiException(ErrorCode.API_SYS_CONFIG_EXISTS_ERROR);
                }

                apiSystemConfigManager.add(buildCreate(json));
            } catch (ApiBizException e) {
                logger.error("APIConfigController->add config :error:{}", e);
                throw new ApiException(ErrorCode.API_SYS_CONFIG_ADD_ERROR);
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        return SUCCESS;
    }

    @RequestMapping(value = "/update")
    public String update(@ModelAttribute RequestMsg requestMsg) {

        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "configKey");
            ValidateUtil.validNotNull(json, "configValue");
            ValidateUtil.validMaxLength(json, "configKey", 60, true);
            ValidateUtil.validMaxLength(json, "configValue", 120, true);
            if (json.containsKey("description")) {
                ValidateUtil.validMaxLength(json, "description", 100, false);
            }
            String configKey = json.getString("configKey").trim();

            try {
                APISystemConfigEntity entity = apiSystemConfigManager.getEntityByKey(configKey);
                if (null == entity) {
                    throw new ApiException(ErrorCode.API_SYS_CONFIG_NOT_EXISTS_ERROR);
                }

                entity.setConfigValue(json.getString("configValue"));
                if (json.containsKey("description")) {
                    entity.setDescription(json.getString("description"));
                }
                apiSystemConfigManager.update(entity);
            } catch (ApiBizException e) {
                logger.error("APIConfigController->update config :error:{}", e);
                throw new ApiException(ErrorCode.OAUTH_CLIENT_UPDATE_ERROR);
            }

        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        return SUCCESS;
    }

    @RequestMapping(value = "/disable")
    public String disable(@ModelAttribute RequestMsg requestMsg) {

        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "configKey");
            ValidateUtil.validMaxLength(json, "configKey", 60, true);
            String configKey = json.getString("configKey").trim();

            try {
                APISystemConfigEntity entity = apiSystemConfigManager.getEntityByKey(configKey);
                if (null == entity) {
                    throw new ApiException(ErrorCode.API_SYS_CONFIG_NOT_EXISTS_ERROR);
                }

                entity.setIsActive("N");
                entity.setIsDelete("Y");

                entity.setUpdated(new Date());
                entity.setUpdatedby("SYSTEM");

                apiSystemConfigManager.update(entity);
            } catch (ApiBizException e) {
                logger.error("APIConfigController->update config :error:{}", e);
                throw new ApiException(ErrorCode.OAUTH_CLIENT_UPDATE_ERROR);
            }

        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        return SUCCESS;
    }

    @RequestMapping(value = "/active")
    public String active(@ModelAttribute RequestMsg requestMsg) {

        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "configKey");
            ValidateUtil.validMaxLength(json, "configKey", 60, true);
            String configKey = json.getString("configKey").trim();

            try {
                APISystemConfigEntity entity = apiSystemConfigManager.selectNonActiveEntityByKey(configKey);
                if (null == entity) {
                    throw new ApiException(ErrorCode.API_SYS_CONFIG_NOT_EXISTS_ERROR);
                }

                entity.setIsActive("Y");
                entity.setIsDelete("N");

                entity.setUpdated(new Date());
                entity.setUpdatedby("SYSTEM");

                apiSystemConfigManager.update(entity);
            } catch (ApiBizException e) {
                logger.error("APIConfigController->update config :error:{}", e);
                throw new ApiException(ErrorCode.OAUTH_CLIENT_UPDATE_ERROR);
            }

        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        return SUCCESS;
    }

    @RequestMapping(value = "/queryByKey")
    public String queryByKey(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "configKey");
            ValidateUtil.validMaxLength(json, "configKey", 60, true);
            String configKey = json.getString("configKey").trim();

            try {
                APISystemConfigEntity entity = apiSystemConfigManager.getEntityByKey(configKey);
                if (null == entity) {
                    throw new ApiException(ErrorCode.API_SYS_CONFIG_QUERY_ERROR);
                }
                Map<String, Object> data = new HashMap<String, Object>();
                data.put("configKey", entity.getConfigKey());
                data.put("configValue", entity.getConfigValue());
                data.put("description", entity.getDescription());

                responseMsg.setData(data);
            } catch (ApiBizException e) {
                logger.error("APIConfigController->query config :error:{}", e);
                throw new ApiException(ErrorCode.OAUTH_CLIENT_UPDATE_ERROR);
            }

        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        return SUCCESS;
    }

    private APISystemConfigEntity buildCreate(JSONObject json) {
        APISystemConfigEntity entity = new APISystemConfigEntity();
        entity.setConfigKey(json.getString("configKey"));
        entity.setConfigValue(json.getString("configValue"));
        entity.setDescription(json.getString("description"));
        entity.setCreated(new Date());
        entity.setCreatedby("system");

        return entity;

    }

}
